package com.jy.rhin.infra.uitl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import sun.security.x509.X509CertImpl;

import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.Security;
import java.util.Date;

/**AuditInfoConverter4TwoWayReferralApproveQuery
 * 生成证书
 */
@Slf4j
public class CertificateUtils {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static String  createPfx(CertAndKey rootCA,String pwd,String alias) {
        String rootCertContent = "";
        try {
            KeyStore outputKeyStore = KeyStore.getInstance("PKCS12");
            outputKeyStore.load(null, pwd.toCharArray());
            X509CertImpl x509Cert = new X509CertImpl(rootCA.getX509CertificateHolder().getEncoded());
            outputKeyStore.setKeyEntry(alias, rootCA.getKeyPair().getPrivate(), pwd.toCharArray(),
                    new X509CertImpl[]{x509Cert});
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            outputKeyStore.store(baos, pwd.toCharArray());
            rootCertContent= Base64.encode(baos.toByteArray());
        } catch (Exception e) {
            log.error("生成pfx证书错误", e);
        }
        return rootCertContent;
    }


    public static String createCrt(CertAndKey rootCA){
        String rootCertContent = "";
        try {
            rootCertContent = java.util.Base64.getEncoder().encodeToString( new String(rootCA.getX509CertificateHolder().getEncoded(), StandardCharsets.UTF_8).getBytes());
            rootCertContent = "-----BEGIN CERTIFICATE-----\n" +
                        lf(rootCertContent, 64)
                        + "-----END CERTIFICATE-----";
           // rootCertContent = Base64.encode();
        } catch (Exception e) {
            log.error("存储crt证书错误", e);
        }
        return Base64.encode((rootCertContent));
    }

    public static String createPriFile(CertAndKey rootCA){
        String rootCertContent = "";
        try {
            rootCertContent = Base64.encode(rootCA.getKeyPair().getPrivate().getEncoded());
        } catch (Exception e) {
            log.error("存储pri证书错误", e);
        }
        return rootCertContent;
    }
    public static CertAndKey createRootCACert(Date startTime, Date endTime,String zhengShuSYZ){

        if(startTime==null){
            startTime= new Date();
        }
        if(endTime==null){
            endTime = DateUtil.offset(new Date(), DateField.YEAR, 10);
        }
        try{
            X500NameBuilder x500NameBuilder = new X500NameBuilder();
            x500NameBuilder.addRDN(BCStyle.C, "CN");
            x500NameBuilder.addRDN(BCStyle.ST, "ZheJiang");
            x500NameBuilder.addRDN(BCStyle.L, "HangZhou");
            x500NameBuilder.addRDN(BCStyle.O, "JuYiZhiLian");
            x500NameBuilder.addRDN(BCStyle.OU, "QuanMinPlat");
            x500NameBuilder.addRDN(BCStyle.CN, zhengShuSYZ);
            //x500NameBuilder.addRDN(BCStyle.CN, "www.juyizhilian.com");
            X500Name root = x500NameBuilder.build();
            KeyPair keyPair = SecureUtil.generateKeyPair("SHA256withSM2");

            Date curr = new Date();
            X509v3CertificateBuilder x509v3CertificateBuilder = new JcaX509v3CertificateBuilder(root
                    , BigInteger.valueOf(curr.getTime())
                    , startTime
                    , endTime
                    , root
                    , keyPair.getPublic())
                    .addExtension(new ASN1ObjectIdentifier("2.5.29.19"),    //指示主体是否可以充当CA，并使用经过认证的公钥来验证证书签名
                            false,
                            new BasicConstraints(true));
            JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder("SHA256withSM2");
            ContentSigner contentSigner = jcaContentSignerBuilder.build(keyPair.getPrivate());
            X509CertificateHolder x509CertificateHolder = x509v3CertificateBuilder.build(contentSigner);
            return new CertAndKey(keyPair, x509CertificateHolder);
        }catch (Exception e){
            log.error("创建CA自签根证书错误", e);
            throw new RuntimeException("创建CA自签根证书错误");
        }
    }

    public static String lf(String str, int lineLength) {
        assert str != null;
        assert lineLength > 0;
        StringBuilder sb = new StringBuilder();
        char[] chars = str.toCharArray();
        int n = 0;
        for (char aChar : chars) {
            sb.append(aChar);
            n++;
            if (n == lineLength) {
                n = 0;
                sb.append("\n");
            }
        }
        if (n != 0)
            sb.append("\n");
        return sb.toString();
    }
}
